Skip to content

feat(loop): optional spec/plan gate — reviewable plan artifact before implementation (issue #100) - #148

Merged
robercano-ghbot merged 1 commit into
mainfrom
feat/issue-100-plan-gate
Jul 16, 2026
Merged

feat(loop): optional spec/plan gate — reviewable plan artifact before implementation (issue #100)#148
robercano-ghbot merged 1 commit into
mainfrom
feat/issue-100-plan-gate

Conversation

@robercano-ghbot

Copy link
Copy Markdown
Collaborator

Summary

Implements #100 — an optional, per-issue spec/plan gate: a reviewable plan artifact (a structured issue comment) that the owner approves before the loop writes any code. Opt-in and off by default, so cheap issues pay zero overhead and this repo's own dogfooding behavior is unchanged.

What was implemented

  • New adapter knob plan.gate in both .claude/gates.json (placeholder, schema-documented) and .claude/self/gates.json (set to off): modes off (default, today's single-pass behavior, byte-identical) | label (gate only issues carrying plan-first) | always (gate every planned issue).
  • loop-census.sh derives a per-candidate plan state from labels (precedence plan-approved > plan-review > plan-first), emits advance_mode=plan|implement-gated|implement next to the chosen advance_ready, and excludes awaiting-owner (plan-review, not yet approved) issues from both advance_ready and fallback_ready (reported as plan_wait=N). Emits nothing new when plan.gate=off.
  • loop-tick.sh threads advance_mode through, re-echoing it only on genuine action=advance dispatch and always before the final verdict line (issue Harden PR-loop tick: deterministic loop-tick.sh with single verdict, in-flight detection, spawn lock #81 byte-identical-verdict contract preserved).
  • loop-event.sh selects one of three ADVANCE prompt variants: plan-only (scope, post a <!-- plan-gate:plan --> marked plan comment via bot-gh, apply plan-review + needs-human (Loop/cockpit: needs-human signal — label + push notification when the loop blocks on the owner #99 signal), write no code/branch/PR), implement-gated (fetch the approved plan comment and inject it into the implementer AND every reviewer prompt, with "diff exceeds approved plan scope" as a valid correctness reject reason), and ungated (unchanged). Reads advance_mode via grep, never tail -1; missing/broken value safely defaults to implement.
  • reviewer.md / orchestrator.md: durable notes so an approved plan is forwarded verbatim as authoritative scope and scope-creep is a valid correctness reject.
  • plan-gate.test.sh (new, auto-discovered by checks.sh): 33 checks driving the real loop-census.sh and loop-event.sh across all six mode/label combinations, including the gate=off byte-identical guarantee and the awaiting-owner skip.
  • docs/USAGE.md: documents the plan-firstplan-reviewplan-approved label lifecycle next to the existing backlog/planned workflow.

Decision points resolved

  • Plan-as-comment, not spec-PR — one artifact per issue, zero extra branches/worktree churn.
  • All three modes (off/label/always) implemented, per the acceptance criteria.
  • Owner-only approval for plan-approved, documented with the same non-enforceable caveat as the existing planned label (the loop checks label presence, not GitHub identity).

Gates & review

  • build, lint, test all green via GATES_FILE=.claude/self/gates.json (test includes the new plan-gate.test.sh (33/33), all pre-existing *.test.sh — loop-census 29, loop-tick 71, loop-event 29 — and smoke-fanout.sh; no regressions).
  • Reviewed and approved through both configured lenses (correctness, tests; consensus=all). The tests reviewer confirmed assertions are load-bearing via mutation testing.

Closes #100

🤖 Generated with Claude Code

Adds gates.json's `plan.gate` knob (off default | label | always) so the
loop can post a reviewable plan comment (marked <!-- plan-gate:plan -->)
and wait for owner approval (plan-review -> plan-approved) before an
issue is implemented, instead of always going straight to code.
loop-census.sh derives each candidate's plan state from its labels and
skips awaiting-owner candidates like a "Blocked by" edge; loop-tick.sh
threads the resulting advance_mode through as telemetry; loop-event.sh
builds a PLAN-ONLY driver prompt, an implement prompt with the approved
plan injected as authoritative scope, or today's unchanged ungated
prompt. gate=off leaves census output byte-identical to pre-#100
behavior. reviewer.md/orchestrator.md gain a short note on honoring an
approved plan's scope; docs/USAGE.md documents the label lifecycle.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@robercano-ghbot

Copy link
Copy Markdown
Collaborator Author

feat(loop): optional spec/plan gate — reviewable plan artifact before implementation (issue #100) (not yet reviewed)

@robercano-ghbot
robercano-ghbot merged commit 89ae951 into main Jul 16, 2026
9 checks passed
@robercano-ghbot
robercano-ghbot deleted the feat/issue-100-plan-gate branch July 16, 2026 17:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Orchestrator: optional spec/plan gate — a reviewable plan artifact before implementation starts

2 participants